package com.example.demo.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.order.dto.request.OrderCreateRequest;
import com.example.demo.order.dto.response.OrderResponse;
import com.example.demo.order.entity.Order;
import com.example.demo.order.enums.OrderStatusEnum;
import com.example.demo.order.exception.BusinessException;
import com.example.demo.order.mapper.OrderMapper;
import com.example.demo.order.rocketmq.producer.OrderProducer;
import com.example.demo.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName OrderServiceImpl
 * @Description
 * @Author MingChang.Wei
 * @Date 2025/8/8
 **/
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private OrderProducer orderProducer;

    @Override
    @Transactional
    public OrderResponse createOrder(OrderCreateRequest request) {
        Order order = new Order();
        BeanUtils.copyProperties(request, order);
        order.setOrderNo(UUID.randomUUID().toString());
        order.setStatus(OrderStatusEnum.CREATED.getCode());
        order.setCreateTime(LocalDateTime.now());
        order.setPrice(new BigDecimal("100")); // 实际应从商品服务获取
        order.setTotalAmount(order.getPrice().multiply(new BigDecimal(order.getQuantity())));
        save(order);

        // 发送创建订单消息到 RocketMQ
        orderProducer.sendCreateOrderMessage(order);

        OrderResponse response = new OrderResponse();
        BeanUtils.copyProperties(order, response);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE, timeout = 30)
    public boolean payOrder(String orderNo) {
        // 分布式锁防止重复支付（推荐使用PaymentService进行支付）
        // 这里是简化版本，完整支付流程请使用PaymentService.initiatePayment
        
        try {
            Order order = getOrderByOrderNo(orderNo);
            if (order == null) {
                throw new BusinessException("订单不存在");
            }
            
            // 注意：这是简化版支付方法，生产环境建议使用PaymentService
            log.info("简化支付流程: orderNo={}, username={}", orderNo, order.getUsername());
            
            // 验证订单状态
            if (!order.getStatus().equals(OrderStatusEnum.CREATED.getCode())) {
                throw new BusinessException("订单状态不允许支付");
            }
            
            // 验证订单金额（简化版本）
            if (order.getTotalAmount() == null || order.getTotalAmount().compareTo(BigDecimal.ZERO) <= 0) {
                throw new BusinessException("订单金额异常");
            }
            
            // 检查订单是否超时（比如30分钟内必须支付）
            if (order.getCreateTime().plusMinutes(30).isBefore(LocalDateTime.now())) {
                // 订单超时，更新状态为已取消
                order.setStatus(OrderStatusEnum.TIMEOUT.getCode());
                updateById(order);
                throw new BusinessException("订单已超时，无法支付");
            }
            
            // 调用支付服务进行实际支付（简化版本，实际应使用PaymentService）
            boolean paymentResult = processPayment(order);
            
            if (paymentResult) {
                // 支付成功，更新订单状态
                order.setStatus(OrderStatusEnum.PAID.getCode());
                order.setPayTime(LocalDateTime.now());
                boolean updateResult = updateById(order);
                
                if (updateResult) {
                    // 发送支付订单消息到 RocketMQ
                    orderProducer.sendPayOrderMessage(orderNo);
                    
                    log.info("订单支付成功: orderNo={}, userId={}, amount={}", 
                               orderNo, order.getUsername(), order.getTotalAmount());
                    return true;
                } else {
                    throw new BusinessException("订单状态更新失败");
                }
            } else {
                throw new BusinessException("支付失败，请重试");
            }
        } catch (Exception e) {
            log.error("订单支付失败: orderNo={}", orderNo, e);
            throw new BusinessException("支付失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理支付逻辑（模拟）
     * 注意：生产环境请使用PaymentService.initiatePayment进行完整的支付流程
     */
    private boolean processPayment(Order order) {
        // 集成真实支付渠道（微信、支付宝等）
        // 实际项目中应该调用：paymentService.initiatePayment(paymentRequest)
        // 这里提供简化版支付处理，仅用于测试
        try {
            // 模拟支付耗时
            Thread.sleep(100);
            
            // 模拟支付成功率（实际项目中不需要）
            return order.getTotalAmount().compareTo(new BigDecimal("50000")) <= 0; // 500元以下支付成功
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    @Transactional
    public boolean refundOrder(String orderNo) {
        Order order = getOrderByOrderNo(orderNo);
        if (order.getStatus().equals(OrderStatusEnum.PAID.getCode())) {
            order.setStatus(OrderStatusEnum.REFUNDED.getCode());
            order.setRefundTime(LocalDateTime.now());
            updateById(order);

            // 发送退款订单消息到 RocketMQ
            orderProducer.sendRefundOrderMessage(orderNo);
            return true;
        }
        return false;
    }

    @Override
    public OrderResponse getOrder(String orderNo) {
        Order order = getOrderByOrderNo(orderNo);
        OrderResponse response = new OrderResponse();
        BeanUtils.copyProperties(order, response);
        return response;
    }

    @Override
    public Page<OrderResponse> getOrderList(String username, Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        Page<Order> orderPage = lambdaQuery()
                .eq(Order::getUsername, username)
                .orderByDesc(Order::getCreateTime)
                .page(page);
        
        // 转换为响应对象
        Page<OrderResponse> responsePage = new Page<>(current, size);
        responsePage.setTotal(orderPage.getTotal());
        
        List<OrderResponse> responseList = orderPage.getRecords().stream()
                .map(order -> {
                    OrderResponse response = new OrderResponse();
                    BeanUtil.copyProperties(order, response);
                    response.setStatusDesc();
                    return response;
                })
                .collect(Collectors.toList());
                
        responsePage.setRecords(responseList);
        return responsePage;
    }

    @Override
    public Order getOrderByOrderNo(String orderNo) {
        return lambdaQuery().eq(Order::getOrderNo, orderNo).one();
    }
}
